package com.springboot.cloud.sysadmin.organization.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.springboot.cloud.sysadmin.organization.dao.RoleMapper;
import com.springboot.cloud.sysadmin.organization.entity.form.RoleResourceForm;
import com.springboot.cloud.sysadmin.organization.entity.param.RoleQueryParam;
import com.springboot.cloud.sysadmin.organization.entity.po.Role;
import com.springboot.cloud.sysadmin.organization.exception.RoleNotFoundException;
import com.springboot.cloud.sysadmin.organization.service.IRoleDeptService;
import com.springboot.cloud.sysadmin.organization.service.IRoleResourceService;
import com.springboot.cloud.sysadmin.organization.service.IRoleService;
import com.springboot.cloud.sysadmin.organization.service.IUserRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Created by ZengJian on 2021/2/3 0003 上午 9:22
 */
@Service
@Slf4j
public class RoleService extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private   IUserRoleService userRoleService;
    @Autowired
    private   RoleMapper roleMapper;
    @Autowired
    private   IUserRoleService userGroupService;
    @Autowired
    private   IUserRoleService userPositionService;
    @Autowired
    private   IRoleResourceService roleResourceService;
    @Autowired
    private   IRoleDeptService roleDeptService;

    @Override
    public boolean add(Role role) {
        Role role1 = this.getOne(new QueryWrapper<Role>().eq(StrUtil.isNotBlank(role.getName()), "name", role.getName()), false);
        if (ObjectUtil.isNull(role1)) {
            boolean isSuccess = this.saveOrUpdate(role);
            String id = role.getId();
            roleDeptService.saveBatch(id, role.getDepts());
            return isSuccess;
        }
        return false;
    }

    @Override
//    @CacheInvalidate(name = "role::", key = "#id")
    public boolean delete(Set<String> ids) {

        for (String id : ids) {
            userRoleService.removeByRoleId(id);
            roleResourceService.removeByRoleId(id);
        }
        log.debug("idss:{}", ids);
        return this.removeByIds(ids);
    }

    @Override
//    @CacheInvalidate(name = "role::", key = "#role.id")
    public boolean update(Role role) {
        Role role1 = this.getById(role.getId());
        if (ObjectUtil.isNull(role1) || role1.getId().equals(role.getId()) && get(role.getId())) {
            return false;
        }
        boolean isSuccess = this.updateById(role);
        if (role.getDataScope().equals("2")) {
            roleDeptService.saveBatch(role.getId(), role.getDepts());
        }
        log.debug("get with group:{}", role.getDepts());
        return isSuccess;
    }

    @Override
//    @CacheInvalidate(name = "role::", key = "#role.id")
    public boolean updateResource(RoleResourceForm roleResourceForm) {
        Role role1 = this.getById(roleResourceForm.getId());
        if (ObjectUtil.isNull(role1)) {
            return false;
        }
        return roleResourceService.saveBatch(roleResourceForm.getId(), roleResourceForm.getResources());
    }

    @Override
    public boolean updateEnabled(Role role) {
        Role role1 = this.getById(role.getId());
        if (ObjectUtil.isNull(role1)) {
            return false;
        }
        return this.updateById(role);
    }

    //    @Override
////    @Cached(name = "role::", key = "#id", cacheType = CacheType.BOTH)
//    public Role get(String id) {
//        Role role = this.getById(id);
//        if (Objects.isNull(role)) {
//            throw new RoleNotFoundException("没有找到id为:" + id+"的角色");
//        }
//        role.setResourceIds(roleResourceService.queryByRoleId(id));
//        role.setDepts(roleDeptService.queryByRoleId(id));
//        log.debug("query queryByRoleId:{}", roleResourceService.queryByRoleId(id)+":roleDeptService.queryByRoleId(id):"+roleDeptService.queryByRoleId(id));
//        return role;
//    }
    @Override
//    @Cached(name = "role::", key = "#id", cacheType = CacheType.BOTH)
    public Role getRole(String id) {
        Role role = this.getById(id);
        if (ObjectUtil.isNull(role)) {
            throw new RoleNotFoundException("没有找到id为:" + id + "的角色");
        }
        role.setResources(roleMapper.getResources(id));
        role.setDepts(roleDeptService.queryByRoleId(id));
        log.debug("query queryByRoleId:{}", roleResourceService.queryByRoleId(id) + ":roleDeptService.queryByRoleId(id):" + roleDeptService.queryByRoleId(id));
        return role;
    }


    public Role getRoleByCode(String code) {
        Role role1 = this.getOne(new QueryWrapper<Role>().eq("code", code), false);
        return role1;
    }

    @Override
    public boolean get(String id) {
        Role role = this.getById(id);
        if (ObjectUtil.isNull(role)) {
            return false;
        }
        return true;
    }

    @Override
    public List<Map<String, Object>> getAll() {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Role::getId, Role::getName);
        return this.listMaps(queryWrapper);

    }

    // 根据用户id查询用户所拥有的角色信息
    @Override
//    @Cached(name = "role4user::", key = "#userId", cacheType = CacheType.BOTH)
    public List<Role> query(String userId) {
        Set<String> roleIds = userRoleService.queryByUserId(userId);
        Set<String> depts = userGroupService.queryByUserId(userId);
        Set<String> positionIds = userPositionService.queryByUserId(userId);
        return (List<Role>) this.listByIds(roleIds);
    }

    @Override
    public IPage<Role> query(Page page, RoleQueryParam roleQueryParam) {
        log.debug("deleteds:{}", roleQueryParam.getDeleted());
        return roleMapper.selectPageListRole(page, roleQueryParam);
    }

}
